// 去别的文件写ko

class LogSystem {
    constructor(sto, config) {
        this._storage = sto;
        this._buffer = [];
        this._preTimestamp = -1;
        this._listening = false;

        this.config = Object.assign({
            checkBufferMS: 100,
            pushRecordMS: 1000,
            lengthLimit: 8,
            errorRetries: 4,
            retryMS: 500,
            readPageSize: 32,
            readPageMS: 1000
        }, config);
    }

    log(content) {
        let timestamp = Date.now();
        if (this._preTimestamp == timestamp) {
            timestamp++;
        }
        this._preTimestamp = timestamp;
        console.log(`[${Date(timestamp)}] ${content}`);

        this._buffer.push({
            timestamp,
            content: content.toString()
        });
    }

    async getList(config) {
        let config_ = Object.assign({
            start: Date.now() - 1000 * 60 * 60,
            end: Date.now()
        }, config);
        if (config_.end < config_.start) {
            throw new Error("Start time is greater than end time");
        }

        let result = [];
        const reader = await this._storage.list({
            cursor: 0,
            pageSize: this.config.readPageSize,
            constraintTarget: "timestamp",
            ascending: false,
            max: config_.end,
            min: config_.start
        });
        while (true) {
            let page = reader.getCurrentPage();
            if (page.length === 0) {
                break;
            }
            page.forEach((record) => {
                result.push(record.value);
            });

            if (reader.isLastPage) {
                break;
            }
            await reader.nextPage();
            await sleep(this.config.readPageMS);
        }

        return result;
    }

    async listen() {
        if (this._listening) {
            return;
        }
        this._listening = true;
        while (this._listening) {
            if (this._buffer.length === 0) {
                await sleep(this.config.checkBufferMS);
                continue;
            }

            let record = this._buffer.shift();
            for (let retries = this.config.errorRetries; retries > 0; retries--) {
                try {
                    await this._storage.set(record.timestamp.toString(), record);
                    break;
                } catch (e) {
                    console.error(e);
                    await sleep(this.config.retryMS);
                }
            }

            if (this._buffer.length > this.config.lengthLimit) {
                continue;
            }
            await sleep(this.config.pushRecordMS);
        }
    }
    stop() {
        this._listening = false;
    }
}

globalThis.logger = new LogSystem(storage.getDataStorage("logs"));
globalThis.logger.listen();

module.exports = { logger };